﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Facebook;

using NutriLeaf.Web.Model;

namespace NutriLeaf.Web.Core.Account
{
    public class User
    {
        string AccessToken; //access token required by facebook
        FacebookClient client; //wrapper object to access facebook
        NutriLeafDBEntities context;
        dynamic me;
        DateTime Expires;

        //constructor
        /// <summary>
        /// User class constructor to get the user data from facebook
        /// </summary>
        /// <param name="accessToken">Access token required by Facebook</param>
        public User(string accessToken,DateTime expires,ref NutriLeafDBEntities context)
        {
            this.context = context;
            AccessToken = accessToken;
            client = new FacebookClient(AccessToken);
            me = client.Get("me");
            Expires = expires;
        }

        public User(ref NutriLeafDBEntities context)
        {

        }

        public bool IsRegistered()
        {
            if (GetUser() == null)
            {
                return false;
            }
            return true;
        }

        public int GetUserID()
        {
                if (IsRegistered())
                {
                    return (from a in context.Users
                            where a.AccessToken == AccessToken
                            select a.UserID).SingleOrDefault();
                }
                else
                {
                    return Convert.ToInt32(me.id);
                }
        }

        public Model.User GetUser()
        {
            return (from a in context.Users
                    where a.AccessToken == AccessToken
                    select a).SingleOrDefault();
        }

        public Model.UserProfile GetUserProfile()
        {
            int userId = GetUserID();
            return (from a in context.UserProfiles
                    where a.UserProfileID==userId
                    select a).SingleOrDefault();
                    
        }

        public UserData GetUserData()
        {
            return new UserData
            {
                profile=GetUserProfile(),
                user=GetUser()
            };
        }

        public void UpdateUserProfile()
        {
            bool userFlag, profileFlag;
            Model.User user = GetUser();
            Model.UserProfile profile = GetUserProfile();
            userFlag = profileFlag = false;
            if (user == null)
            {
                user = new Model.User();
                userFlag = true;
                user.DateTimeStamp = DateTime.Now;
            }
            
            if (DateTime.Parse(me.updated_time) > user.DateTimeUpdated||userFlag)
            {

                if (profile == null)
                {
                    profile = new UserProfile();
                    profileFlag = true;
                    profile.DateTimeAdded = DateTime.Now;
                }

                //adding all the details 
                if (me.id != null)
                {
                    user.UserID = Convert.ToInt32(me.id);
                    profile.UserProfileID = user.UserID;
                }
                if (me.name != null)
                {
                    profile.Name = me.name;
                }
                if (me.first_name != null)
                {
                    profile.FirstName = me.first_name;
                }
                if (me.last_name != null)
                {
                    profile.LastName = me.last_name;
                }
                if (me.link != null)
                {
                    profile.Link = me.link;
                }
                if (me.username != null)
                {
                    user.Username = me.username;
                }
                if (me.birthday != null)
                {
                    profile.Birthday = DateTime.Parse(me.birthday);
                    profile.Age = DateTime.Now.Year - profile.Birthday.Value.Year;
                }

                if (me.gender != null)
                {
                    if (me.gender == "male")
                    {
                        profile.Gender = true;
                    }
                    if (me.gender == "female")
                    {
                        profile.Gender = false;
                    }
                }

                if (me.email != null)
                {
                    user.Email = me.email;
                }

                if (me.timezone != null)
                {
                    profile.Timezone = (float)me.timezone;
                }

                if (me.locale != null)
                {
                    user.Locale = me.locale;
                }

                if (me.verified != null)
                {
                    user.UserActivated = me.verified;
                }

                if (me.updated_time != null)
                {
                    user.DateTimeUpdated = DateTime.Parse(me.updated_time);
                    profile.DateTimeUpdated = DateTime.Parse(me.updated_time);
                }


                user.Expires = Expires;
                user.AccessToken = AccessToken;

                //add to context
                if (userFlag)
                {
                    context.AddToUsers(user);
                }

                if (profileFlag)
                {
                    context.AddToUserProfiles(profile);
                }

                context.SaveChanges();
            }
        }

        public static bool IsRegistered(int userId,ref NutriLeafDBEntities context)
        {
            Model.User user = (from a in context.Users
                               where a.UserID == userId
                               select a).SingleOrDefault();

            if (user == null)
            {
                return false;
            }
            return true;
        }

        public static int GetUserID(string accessToken, ref NutriLeafDBEntities context)
        {
            User user = new User(accessToken, DateTime.Now.AddYears(1000), ref context);
            return user.GetUserID();
        }

        public static UserProfile GetUserProfile(int userId, ref NutriLeafDBEntities context)
        {
            return (from a in context.UserProfiles
                    where a.UserProfileID == userId
                    select a).SingleOrDefault();
        }

        public static Model.User GetUser(int userId, ref NutriLeafDBEntities context)
        {
            return (from a in context.Users
                    where a.UserID == userId
                    select a).SingleOrDefault();
        }

        public static UserData GetUserData(int userId, ref NutriLeafDBEntities context)
        {
            return new UserData
            {
                profile = GetUserProfile(userId,ref context),
                user = GetUser(userId,ref context)
            };
        }

        public static void UpdateUserProfile(Model.UserProfile userProfile, ref NutriLeafDBEntities context)
        {
            if (userProfile != null)
            {
                context.SaveChanges();
            }
        }

        public static void UpdateUser(Model.User user, ref NutriLeafDBEntities context)
        {
            if (user != null)
            {
                context.SaveChanges();
            }
        }

        public static void UpdateUserData(UserData userdata, ref NutriLeafDBEntities context)
        {
            UpdateUser(userdata.user, ref context);
            UpdateUserProfile(userdata.profile, ref context);
        }

        public static void UpdateUserProfile(string accesstoken, ref NutriLeafDBEntities context)
        {
            User user = new User(accesstoken, DateTime.Now.AddTicks(1000), ref context);
            user.UpdateUserProfile();
        }

    }
}